<script setup lang="ts">
import { Message } from '@/instance';
import useEmit from '@/hooks/useEmitter';
import usePageSave from '@/hooks/usePageSave';
import useSticky from '@/hooks/useSticky';
import { modalTableConfig } from './config/table-config';
import { formConfig } from './config/form-config';
import {
    formatInput,
    handleDelKey,
    transformDataToKeys,
    filterByKey,
    transformValue
} from '@/utils';
import { initAddRow, initDefault } from '@/components/base-ui/base-table/hooks/useTableAction';
import { generateNameToLevel } from '@/config/constant';
import { doAddProcess } from '@/api/modeling/ProcessManagement/index';
import { ArrowUp, ArrowDown } from '@element-plus/icons-vue';
import { cloneDeep } from 'lodash-es';
import type {
    WorkingProcedureVO,
    MaterialChooseVO,
    TechnologicalProcessDTO,
    WorkingProcedureEquipmentDTO
} from '@/api/modeling/ProcessManagement/model/type';
import ProcedureCode from '../../dialog/procedureCode/index.vue';
import MateriaCode from '../../dialog/materiaCode/index.vue';

defineOptions({
    name: 'ProcessManagementAdd'
});

const STORE_KEY = 'processAddData';
const { startRecording, isUpdate } = useEmit(STORE_KEY);

interface ProcessRouteForm {
    [key: string]: string | null;
    processRouteCode: string | null;
    processRouteName: string | null;
    processRouteDesc: string | null;
    materialCode: string | null;
    remarks: string | null;
}

const initProcessRouteForm = () => {
    return {
        processRouteCode: null,
        processRouteName: null,
        processRouteDesc: null,
        materialCode: null,
        remarks: null
    };
};

const processRouteForm = ref<ProcessRouteForm>(initProcessRouteForm());

/**
 * 数据复制，初始化数据
 */
const store = addDataStore();
const route = useRoute();
const initData = () => {
    const defaultData = {};
    initDefault(defaultData, modalTableConfig.items);
    processRouteForm.value = initProcessRouteForm();
    tableRef.value.setTableData([{ ...initAddRow(), ...defaultData }]);

    startRecording(route.name as string, {
        processRouteForm,
        tableData: tableRef.value?.tableData
    });
};

/**
 * 重置数据
 */
const resetData = () => {
    processRouteForm.value = initProcessRouteForm();
    validMaterialId.value = null;
    processMaterialId.value = null;
    processMaterialCode.value = null;
    selectProcedureId.value = null;
    validProcedureId.value = null;
};

onActivated(() => {
    isUpdate(initData);
});

onUnmounted(() => {
    store.handleAddData(STORE_KEY);
    resetData();
});

/**
 * 校验相关
 */
const {
    popoverVisible,
    popoverErrMsg,
    handleInput,
    handleFocus,
    handleValidFieldPass,
    resetRelatedValid,
    setValidErrorVisible
} = useValid({
    position: 'left',
    formConfig: formConfig.items,
    formFields: processRouteForm,
    mountErrId: formConfig.id
});

/**
 * 点击保存所调用 hook
 */
const { loading, modalSlotRef: tableRef, modalOk } = useModal({ appendData: processRouteForm });

const addData = async () => {
    let tableData: TechnologicalProcessDTO[] = cloneDeep(tableRef.value.tableData);
    const technologicalProcess = tableData.map(item => {
        return transformDataToKeys(item, [
            'processId',
            'processNumber',
            'processCode',
            'processName',
            'replacementTime',
            'transshipmentBatch',
            'transshipmentTime',
            'processingContent',
            'processEquipments'
        ]);
    });

    const data = {
        materialId: processMaterialId.value,
        ...processRouteForm.value,
        technologicalProcess
    };

    try {
        const res = await doAddProcess(data);

        if (res) {
            Message.success('操作成功！');
        }

        return res;
    } catch (error) {
        console.error(error);
    }
};

/**
 * 点击物料编码
 */
const validMaterialId = ref(); // 记录当前校验 id 用于清除表格验证
const materialCodeVisible = ref(false);
const handleClickMaterialCode = (id: string) => {
    validMaterialId.value = id;
    materialCodeVisible.value = true;
};

// 选择物料编码，点击保存
const processMaterialId = ref(); // 工序 id
const processMaterialCode = ref(); // 工序编码
const handleMaterialCodeOk = (materialData: MaterialChooseVO) => {
    resetRelatedValid([validMaterialId.value]);
    processMaterialId.value = materialData.id;
    processMaterialCode.value = materialData.materialCode;
    processRouteForm.value.materialCode = materialData.materialCode!;
};

/**
 * 工序编码
 */
const selectProcedureId = ref(); // 记录当前选项 id 用于数据填充
const validProcedureId = ref(); // 记录当前校验 id 用于清除表格验证
const validIndex = ref(0); // 校验列表索引
const procedureId = ref();
const processCode = ref(); // 工序编码
const procedureCodeVisible = ref(false);

// 点击工序编码选择
const handleClickProcedureCode = (row: anyObj, id: number | string, index: number) => {
    selectProcedureId.value = row.id;
    validProcedureId.value = id;
    validIndex.value = index;
    procedureId.value = row.processCode ? row.processId : ''; // 防止清空工序编码，数据回显 bug
    processCode.value = row.processCode;
    procedureCodeVisible.value = true;
};

/**
 * 选择工序编码，点击保存
 */
const handleProcedureCodeOk = (procedureCodes: WorkingProcedureVO) => {
    if (!procedureCodes || !Object.keys(procedureCodes).length) return;
    resetRelatedValid([validProcedureId.value], validIndex.value); // 清除选项校验

    // 过滤出当前所选的 id 项
    const currentOption = filterByKey(tableRef.value.tableData, selectProcedureId.value);
    if (currentOption) {
        for (let key in procedureCodes) {
            if (key === 'id') {
                currentOption['processId'] = procedureCodes[key];
                continue;
            }
            currentOption[key] = procedureCodes[key];
        }

        currentOption['processingContent'] = procedureCodes['remark']; // 加工内容

        currentOption['processEquipments'] = procedureCodes['workingProcedureEquipments']
            ?.map(item => {
                if (item.workingProcedureAuxiliary?.length) {
                    item.workingProcedureAuxiliary = item.workingProcedureAuxiliary.map(
                        (j: any) => {
                            Object.keys(item).forEach(k => {
                                if (k !== 'workingProcedureAuxiliary') j[k] = item[k] as any;
                            });
                            j['auxiliaryDataId'] = j['auxiliaryId'];
                            j['equipmentCode'] = j['equipmentNumber'];
                            return handleDelKey(j, ['equipmentNumber', 'auxiliaryId']);
                        }
                    );
                    return item.workingProcedureAuxiliary || {};
                } else {
                    item['equipmentCode'] = item['equipmentNumber'];
                    return handleDelKey(item, ['equipmentNumber', 'workingProcedureAuxiliary']);
                }
            })
            .flat();

        markSameEquipment(currentOption['processEquipments']);
    }
};

/**
 * 标记当前相同加工设备不同辅助资源数据
 */
const markSameEquipment = (list: WorkingProcedureEquipmentDTO[]) => {
    const markMap = new Map(); // 关系映射
    list.map(item => {
        if (!markMap.get(item.equipmentCode)) {
            item.show = true;
            markMap.set(item.equipmentCode, true);
        }
    });
};

/**
 * 收起/展开
 */
interface FormItems extends ItemConfig {
    hidden?: boolean;
}
const isExpand = ref(true);
const formItems = ref<FormItems[]>(formConfig.items);
watch(
    () => isExpand.value,
    val => {
        if (val) {
            formItems.value.forEach(item => (item.hidden = false));
        } else {
            formItems.value.forEach((item, index) => {
                if (!index) {
                    item.hidden = false;
                } else {
                    item.hidden = true;
                }
            });
        }
    }
);

/**
 * 拖拽表格头部 header 宽度自定义
 */
interface WidthList {
    [key: string]: string;
}
const widthList = reactive<WidthList>({});
const handleHeaderDragend = (newWidth: number, __: number, column: any) => {
    widthList[column.label] = `${newWidth}px`;
};

/**
 * 点击保存按钮
 */
const handleOk = async () => {
    try {
        const formValid = handleValidFieldPass();
        const tableValid = tableRef.value?.handleValidFieldPass();

        if (!formValid || !tableValid) return;
        await modalOk(addData, true);
        usePageSave('/process');
    } catch (e) {
        console.log(e);
    }
};

/**
 * 全屏
 */
const fullscreenRef = ref();
const expand = computed(() => fullscreenRef.value && fullscreenRef.value.expand);
const { detailPageSticky } = useSticky(true); // 头部吸顶
</script>

<template>
    <q-page>
        <div :id="generateNameToLevel('4')" class="m-process__page">
            <!-- 基础信息 -->
            <div class="m-title">
                <h2 class="m-title--common m-b-8">基础信息</h2>
                <q-fullscreen ref="fullscreenRef" />
            </div>
            <q-form-item :id="formConfig.id!" class="form-placeholder"></q-form-item>
            <el-row :gutter="32" class="m-b-24">
                <el-col
                    v-for="item in formItems"
                    :key="item.validProps?.id"
                    :span="6"
                    class="role-main__header form-common m-b-18"
                    :style="{ display: item.hidden ? 'none' : 'block' }"
                >
                    <label class="is-column">
                        <span v-if="item.validProps?.required">*</span>
                        {{ item.columnProps?.label }}:
                    </label>
                    <q-form-item
                        v-if="!item.itemType || item.itemType === 'text'"
                        :id="item.validProps?.id!"
                    >
                        <el-input
                            v-model="processRouteForm[item.modelKey!]"
                            :placeholder="`请输入${item.columnProps?.label}`"
                            v-bind="item.elInputProps"
                            @focus="
                                (e: any) =>
                                    handleFocus(e, processRouteForm, {
                                        config: item
                                    })
                            "
                            @input="
                                processRouteForm[item.modelKey!] = formatInput(
                                    processRouteForm,
                                    item.modelKey!,
                                    item.validFormatType
                                )
                            "
                            @keyup="
                                (e: any) =>
                                    handleInput(e, processRouteForm, {
                                        config: item
                                    })
                            "
                            @blur="setValidErrorVisible(false)"
                        />
                    </q-form-item>
                    <q-form-item v-else-if="item.itemType === 'other'" :id="item.validProps?.id!">
                        <q-virtual-select
                            v-model="processRouteForm[item.modelKey!]"
                            placeholder="请选择物料编码"
                            @click="handleClickMaterialCode(item.validProps?.id!)"
                        />
                    </q-form-item>
                </el-col>
                <el-col :span="6" class="m-but"
                    ><span @click="isExpand = !isExpand"
                        >{{ isExpand ? '收起' : '展开'
                        }}<el-icon v-if="isExpand" class="u-icon"><ArrowUp color="#06f" /></el-icon>
                        <el-icon v-else class="u-icon"><ArrowDown color="#06f" /></el-icon>
                    </span>
                </el-col>
            </el-row>

            <!-- 工序信息 -->
            <h2 class="m-title--common m-b-16">工序信息</h2>
            <base-table
                :id="generateNameToLevel('1')"
                ref="tableRef"
                :add-table-row="true"
                :openSticky="true"
                :tableConfig="modalTableConfig"
                body-row-height="56px"
                :class="{ 'is-fullscreen': expand }"
                @header-dragend="handleHeaderDragend"
            >
                <template #index>
                    <el-table-column type="index" label="工序号" width="100">
                        <template #default="{ $index }"
                            ><span class="l-h-32">{{ $index + 1 }}</span></template
                        >
                    </el-table-column>
                </template>
                <!-- 工序编码 -->
                <template #processCode="{ row, item, index }">
                    <q-virtual-select
                        v-model="row.processCode"
                        placeholder="请选择"
                        @click="handleClickProcedureCode(row, item.validProps?.id!, index)"
                    />
                </template>
                <!-- 工序名称 -->
                <template #processName="{ row }">
                    <span class="l-h-32">{{ row.processName || '--' }}</span>
                </template>
                <!-- 加工设备 -->
                <template #workingProcedureEquipments="{ row }">
                    <template v-if="row.processEquipments">
                        <template v-for="item in row.processEquipments" :key="item.equipmentId">
                            <q-tooltip
                                :content="transformValue(item.equipmentCode)"
                                :class="['l-h-32', 'p-b-6', { 'is-hide': !item.show }]"
                            />
                        </template>
                    </template>
                    <template v-else>--</template>
                </template>
                <!-- 辅助资源 -->
                <template #workingProcedureAuxiliary="{ row }">
                    <template v-if="row.processEquipments">
                        <template v-for="item in row.processEquipments" :key="item.auxiliaryId">
                            <q-tooltip
                                :content="transformValue(item.auxiliaryDataCoding)"
                                class="l-h-32 p-b-6"
                            />
                        </template>
                    </template>
                    <template v-else>--</template>
                </template>
                <!-- 加工批量 -->
                <template #workingProcedureList1="{ row, item, validFn }">
                    <template v-if="row.processEquipments">
                        <q-form-item
                            v-for="auxiliary in row.processEquipments"
                            id="1"
                            :key="auxiliary.auxiliaryId"
                            class="p-b-6"
                        >
                            <el-input-number
                                v-model="auxiliary.processingBatch"
                                placeholder="请输入"
                                :controls="false"
                                :precision="0"
                                :min="1"
                                v-bind="item.elInputNumberProps"
                                @focus="
                                    (e: any) =>
                                        validFn.handleFocus(e, auxiliary, {
                                            config: item
                                        })
                                "
                                @keyup="
                                    (e: any) =>
                                        validFn.handleInput(e, auxiliary, {
                                            config: item
                                        })
                                "
                                @blur="validFn.setValidErrorVisible(false)"
                            />
                        </q-form-item>
                    </template>
                    <template v-else>--</template>
                </template>
                <!-- 生产节拍 -->
                <template #workingProcedureList2="{ row, item, validFn }">
                    <template v-if="row.processEquipments">
                        <q-form-item
                            v-for="auxiliary in row.processEquipments"
                            id="2"
                            :key="auxiliary.auxiliaryId"
                            class="p-b-6"
                        >
                            <el-input-number
                                v-model="auxiliary.productionBeat"
                                placeholder="请输入"
                                :controls="false"
                                :precision="0"
                                :min="1"
                                v-bind="item.elInputNumberProps"
                                @focus="
                                    (e: any) =>
                                        validFn.handleFocus(e, auxiliary, {
                                            config: item
                                        })
                                "
                                @keyup="
                                    (e: any) =>
                                        validFn.handleInput(e, auxiliary, {
                                            config: item
                                        })
                                "
                                @blur="validFn.setValidErrorVisible(false)"
                            />
                        </q-form-item>
                    </template>
                    <template v-else>--</template>
                </template>
            </base-table>
            <!-- 校验提示框 -->
            <q-valid-popover
                :popover-visible="popoverVisible"
                :popover-err-msg="popoverErrMsg"
                position="left"
            />

            <!-- 物料编码 -->
            <MateriaCode
                :id="processMaterialId"
                v-model:visible="materialCodeVisible"
                :material-code="processMaterialCode"
                @ok="handleMaterialCodeOk"
            />

            <!-- 工序编码 -->
            <ProcedureCode
                :id="procedureId"
                v-model:visible="procedureCodeVisible"
                :process-code="processCode"
                @ok="handleProcedureCodeOk"
            />
        </div>

        <q-submit-button
            size="default"
            :hide-label="true"
            align="right"
            :horizontal="true"
            :cancel-button="false"
            :close-pseudo="true"
            :loading="loading"
            :style="detailPageSticky ? { bottom: '-48px' } : null"
            class="p-t-8 p-b-8"
            @save="handleOk"
        >
        </q-submit-button>
    </q-page>
</template>

<style lang="scss" scoped>
@include b(m-expand) {
    @include e(list) {
        @include flex(flex-end);

        border-bottom: 1px solid #eee;
    }

    @include e(form) {
        @include m(item) {
            box-sizing: border-box;
            padding: 8px 12px;

            :deep() {
                .el-input-number {
                    width: 99%;
                }
            }
        }
    }

    @include e(text) {
        box-sizing: border-box;
        padding: 0 12px;
    }
}

@include b(m-but) {
    @include flex(flex-start);

    margin-top: 10px;
    font-size: 14px;
    color: var(--q-color-primary);

    & > span {
        display: inline-block;
        padding: 8px 15px;
        cursor: pointer;
        border-radius: 4px;

        &:hover {
            background-color: var(--el-fill-color-light);
        }
    }
}

@include b(u-icon) {
    position: relative;
    top: 2px;
    margin-left: 4px;
}

@include b(is-hide) {
    visibility: hidden;
}

.m-process__page {
    flex: 1;

    :deep() {
        .row-expand--cover {
            .el-table__expand-icon {
                display: none;
            }
        }

        .el-table__expanded-cell {
            padding: 0;
        }

        .el-table .el-table__cell {
            vertical-align: top;
        }

        .el-table__body-wrapper .el-table-column--selection .el-checkbox {
            position: relative;
            top: 4px;
        }

        .m-table__header {
            position: sticky;
            top: 55px;
            z-index: 11;
            width: 100%;
        }

        .header-sticky .el-table__header-wrapper {
            top: 95px;
        }

        .is-fullscreen {
            .m-table__header {
                top: -7px;
            }

            .header-sticky .el-table__header-wrapper {
                top: 32px;
            }

            .m-table__errMsg {
                top: 25px;
            }
        }

        .m-table__errMsg {
            position: sticky;
            top: 88px;
            z-index: 111;
        }
    }
}
</style>
